#ifndef AT_NETWORK_STREAM_h
#define AT_NETWORK_STREAM_h

#include "base_define.h"

// CPU片段释放
#define AT_YIELD() delay(0)

#define GSM_SIZE_IMEI 16 // IMEI内存大小
#define GSM_SIZE_IPV4 16 // IPV4内存大小
#define GSM_SIZE_IPV6 40 // IPV6内存大小

#define AT_NETWORK_TIMEOUT -1 // 返回值匹配超时
#define AT_RCODE1 1           // 返回值1已匹配
#define AT_RCODE2 2           // 返回值2已匹配
#define AT_RCODE3 3           // 返回值3已匹配
#define AT_RCODE4 4           // 返回值4已匹配
#define AT_RCODE5 5           // 返回值5已匹配

#define AT_ERR "ERORR"
#define AT_OK "OK"

typedef const char *AtKey;

class AtNetworkStream {
  protected:
    size_t buffer_size; // 缓冲区大小
    size_t buffer_len;  // 缓冲区长度
    char *buffer;       // 缓冲区栈堆

  public:
    Stream *_stream;

  public:
    /** 串口-发送数据(模板化输出) */
    template <typename... Args>
    inline void streamPrintfClear(const char *format, Args... a) {
      this->streamReleaseInvalidLegacyData();
      this->streamPrintf(format, a...);
    };

    /** 串口-发送数据(模板化输出) */
    template <typename... Args>
    inline void streamPrintf(const char *format, Args... a) {
      this->_stream->printf(format, a...);
      this->buffer_len = 0;
    };

    /** 串口-发送数据(发送之前会清理串口) */
    template <typename T, typename... Args>
    inline void streamWriteClear(T fval, Args... a) {
      this->streamReleaseInvalidLegacyData();
      this->streamWrite(fval, a...);
    };

    /** 串口-发送数据 */
    template <typename T, typename... Args>
    inline void streamWrite(T fval, Args... a) {
      this->_stream->print(fval);
      this->streamWrite(a...);
    };

    /** 串口-发送数据(发送之前会清理串口) */
    template <typename T>
    inline void streamWriteClear(T last) {
      this->streamReleaseInvalidLegacyData();
      this->streamWrite(last);
    };

    /** 串口-发送数据 */
    template <typename T>
    inline void streamWrite(T last) {
      this->_stream->print(last);
      this->buffer_len = 0;
    };

    /**
     * 串口-读取指定结尾的字符
     * @param buf 字符缓冲区
     * @param lenght 最大字符长度
     * @param lastc 最后字符
     */
    size_t streamGet(char *buf, size_t lenght, int lastc);

    /**
     * 串口-读取指定结尾的字符
     * @param buf 字符缓冲区
     * @param lenght 最大字符长度
     */
    inline size_t streamGet(char *buf, size_t lenght) {
      return this->streamGet(buf, lenght, -1);
    };

    /**
     * 串口-读取Float
     * @param len 最大字符长度
     * @param lastc 结束字符
     */
    float streamGetFloat(size_t len, char lastc);

    /**
     * 串口-读取Int
     * @param len 最大字符长度
     * @param lastc 结束字符
     */
    int streamGetInt(size_t len, char lastc);
    /**
     * 串口-读取Float
     * @param len 字符长度
     */
    inline float streamGetFloat(size_t len) {
      return this->streamGetFloat(len, '\0');
    }

    /**
     * 串口-读取Int
     * @param len 字符长度
     */
    inline int streamGetInt(size_t len) {
      return this->streamGetInt(len, '\0');
    };

    /** 串口-释放缓冲区无效数据 */
    void streamReleaseInvalidLegacyData();

    /** 串口-跳过指定内容数据 */
    bool streamSkipUntil(char c);
};

#endif